package com.zj.album.graphy;

import android.os.AsyncTask;
import android.text.TextUtils;

import com.zj.album.graphy.module.PhotoInfo;
import com.zj.album.cache.SizeDisplayUtils;
import com.zj.album.interfaces.CompletedListener;
import com.zj.album.interfaces.PhotoEvent;
import com.zj.album.services.Constancs;

import java.io.File;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.List;

/**
 * Created by zhaojie on 2017/10/20.
 */

public class PhotographHelper {

    private PhotographHelper() {
    }

    private static PhotographHelper helper;

    public static PhotographHelper getHelper() {
        if (helper == null) helper = new PhotographHelper();
        return helper;
    }

    private PhotoTemporaryCache photoTemporaryCache;

    public void init(String cacheNameCode) {
        photoTemporaryCache = new PhotoTemporaryCache(cacheNameCode);
    }

    //当前文件夹内所有的图片
    private List<PhotoInfo> allPhotos = new ArrayList<>();

    private List<Integer> rankModules = new ArrayList<>();

    public List<Integer> getRankModules() {
        return rankModules;
    }

    public void addRankModule(boolean state, int position) {
        List<Integer> rs = new ArrayList<>();
        if (state) {
            rs.add(position);
        }
        for (int module : rankModules) {
            if (module != position) rs.add(module);
        }
        rankModules.clear();
        rankModules.addAll(rs);
        rs.clear();
    }

    private String animateUri = "a";

    public final List<PhotoInfo> getAllPhotos() {
        return allPhotos;
    }


    /**
     * 从临时缓存内删除,注意！仅临时缓存
     */
    public void removeSelectedPhoto(String uri, PhotoEvent event) {
        photoTemporaryCache.deleteOne(uri);
        setAllPhotosSync(false, uri);
        if (event != null)
            event.onEvent(Constancs.helperEventCode_SelectedChange, true);
    }

    //添加一个临时缓存，注意！仅临时缓存
    public void addSelectedPhoto(String uri, PhotoEvent event) {
        photoTemporaryCache.addAChoosePhoto(uri);
        setAllPhotosSync(true, uri);
        if (event != null)
            event.onEvent(Constancs.helperEventCode_SelectedChange, true);
    }

    /**
     * 与所有图片进行选择同步，有所有图片的情况下；
     */
    private void setAllPhotosSync(boolean isSelected, String uri) {
        if (allPhotos != null && allPhotos.size() > 0)
            for (PhotoInfo info : allPhotos) {
                if (info.uri.equals(uri)) {
                    info.isSelector = isSelected;
                    return;
                }
            }
    }

    /**
     * 保存临时缓存
     */
    public void saveSelectedPhotos(String cacheNameCode) {
        PhotoTemporaryCache.saveImageCache(cacheNameCode);
    }

    /**
     * 获取当前已选择的临时缓存
     */
    public List<PhotoInfo> getCurSelectedPhotos(String cacheNameCode) {
        if (photoTemporaryCache == null) init(cacheNameCode);
        return photoTemporaryCache.getChoosePhotos();
    }

    /**
     * 当前已选择的临时缓存数
     **/
    public int curSelectedSize(String cacheNameCode) {
        if (photoTemporaryCache == null) init(cacheNameCode);
        return photoTemporaryCache.getChoosePhotos().size();
    }

    /**
     * 更新用户选择相册的列表，将由服务器返回的字段重新设置用户已选择的图片文件；
     * <p/>
     * 这个操作只是在服务器进行数据同步，不影响数据缓存，即便服务器出错也可缓存用户之前选择的图片文件；
     * 调用该方法，必须在获取全部图片之后，在设置数据显示之前。
     */
    public void syncUserChooseImgForServer(List<String> uris, String cacheNameCode, CompletedListener listener) {
        if (photoTemporaryCache == null) init(cacheNameCode);
        new SyncChooseTask(uris, cacheNameCode, this, listener).execute();
    }

    private static class SyncChooseTask extends AsyncTask<String, Integer, List<String>> {

        private List<String> uris;
        private String cacheNameCode;
        private WeakReference<PhotographHelper> wek_helper;
        private CompletedListener listener;

        public SyncChooseTask(List<String> uris, String cacheNameCode, PhotographHelper helper, CompletedListener listener) {
            this.uris = new ArrayList<>(uris);
            this.cacheNameCode = cacheNameCode;
            this.wek_helper = new WeakReference<>(helper);
            this.listener = listener;
        }

        @Override
        protected List<String> doInBackground(String... strings) {
            List<String> existsUris = new ArrayList<>();
            if (uris != null && uris.size() > 0) {
                for (String uri : uris) {
                    if (!TextUtils.isEmpty(uri)) {
                        File file = new File(uri.replaceAll("file://", ""));
                        if (file.exists() && !file.isDirectory()) {
                            boolean isContainInFilter = false;
                            for (String filter : Manifest.ignore) {
                                if (!TextUtils.isEmpty(filter) && uri.indexOf(filter) > 0) {
                                    isContainInFilter = true;
                                    break;
                                }
                            }
                            if (!isContainInFilter) {
                                existsUris.add(uri);
                                if (wek_helper != null && wek_helper.get() != null)
                                    wek_helper.get().setAllPhotosSync(true, uri);
                            }
                        }
                    }
                }
            }
            return existsUris;
        }

        @Override
        protected void onPostExecute(List<String> existsUris) {
            List<PhotoInfo> existsFiles = new ArrayList<>();
            for (String uri : existsUris) {
                existsFiles.add(new PhotoInfo(uri, true));
            }
            if (wek_helper != null && wek_helper.get() != null && existsFiles.size() > 0) {
                wek_helper.get().photoTemporaryCache.saveAChoosePhotoList(existsFiles);
                PhotoTemporaryCache.refreshImageCache(cacheNameCode, existsFiles);
            }
            uris.clear();
            uris = null;
            wek_helper = null;
            listener.Success(cacheNameCode, existsUris);
        }
    }

    /**
     * 设置一个相册列表，当读取系统文件后，将缓存内图片和所有图片做操作融合
     * <p>
     * 融合前，先排除已经不存在的文件；
     */

    public void setAsAllPhotos(List<PhotoInfo> infos, String cacheNameCode, PhotoEvent event) {
        if (infos == null || infos.size() == 0) {
            event.onEvent(Constancs.helperEvenErroCode, true);
            return;
        }
        allPhotos.clear();
        allPhotos.addAll(getAbsPhotos(infos));
        if (allPhotos == null || allPhotos.size() <= 0) {
            event.onEvent(Constancs.helperEvenErroCode, true);
            return;
        }
        if (photoTemporaryCache == null) init(cacheNameCode);
        List<PhotoInfo> ps = photoTemporaryCache.getChoosePhotos();
        if (ps == null || ps.size() == 0) {
            event.onEvent(Constancs.helperEventCode, true);
            return;
        }
        for (PhotoInfo info : allPhotos) {
            for (PhotoInfo i : ps) {
                if (info.uri.equals(i.uri)) {
                    info.isSelector = true;
                    info.index = i.index;
                }
            }
        }
        ps.clear();
        event.onEvent(Constancs.helperEventCode, true);
    }

    //获取保证存在的列表
    private List<PhotoInfo> getAbsPhotos(List<PhotoInfo> ps) {
        List<PhotoInfo> hasFiles = new ArrayList<>();
        for (PhotoInfo i : ps) {
            File f = new File(i.uri.replaceAll("file://", ""));
            if (f.exists() && !f.isDirectory() && SizeDisplayUtils.getAutoFileOrFilesSize(f) > 0) {
                hasFiles.add(i);
            }
        }
        return hasFiles;
    }


    /**
     * [0]包含返回 0，不包含返回1 ；
     * [1]返回当前顺序值，每次都返回该数据在已选中列表内的序列号+1；
     * 如果不包含，则会返回当前size+1
     */
    public int[] isContainInSelected(String cacheNameCode, String uri) {
        if (photoTemporaryCache == null) init(cacheNameCode);
        List<PhotoInfo> infos = photoTemporaryCache.getChoosePhotos();
        int isContain = 1, index = infos.size() + 1;
        for (PhotoInfo info : infos) {
            if (info.uri.equals(uri)) {
                isContain = 0;
                index = infos.indexOf(info) + 1;
                break;
            }
        }
        return new int[]{isContain, index};
    }

    /**
     * 1。进行已选择列表的更新，该更新作为缓存保存，即使以后进来，也能读取已选择数据；
     * 2。更改已储存的图片列表数据，该数据将在完全离开页面之后失效
     */
    public void onSelectedChanged(boolean state, String uri, String cacheNameCode, PhotoEvent event) {
        if (photoTemporaryCache == null) init(cacheNameCode);
        if (state) {
            addSelectedPhoto(uri, event);
        } else {
            removeSelectedPhoto(uri, event);
        }
    }

    public boolean isNeedUpAnimate(String uri) {
        return animateUri.equals(uri);
    }

    public void upDateAnimUrl(String uri) {
        animateUri = uri;
    }

    public void clearSelectedCache() {
        photoTemporaryCache.destroy();
        photoTemporaryCache = null;
        rankModules.clear();
        rankModules = null;
        allPhotos.clear();
        allPhotos = null;
        helper = null;
    }
}
